A squaring block is something that multiplies a signal by itself, as the name suggests.

3.14. Mimic the code in speccos with Ts=1/1000 to find the spectrum of y(t), a squaring of the signals:

  1. x(t) = cos(2pif*t) for f = 100Hz
  2. cos(2pif1t)+cos(2pif2t) for f1=100Hz, f2=150Hz
  3. filtered noise with spectrum between 100 and 300Hz.
In [7]:
import scipy.signal

def plotspec(x, Ts):
    fig = figure()
    ax1 = fig.add_subplot(211)
    ax1.plot(x)
    
    q = fft.fft(x)
    ax2 = fig.add_subplot(212)
    ax2.plot(fft.fftfreq(len(x), Ts), abs(q))
    
def arbspec(s, time, Ts):
    t = linspace(0.0, time, time/Ts)
    x = s(t)
    plotspec(x, Ts)
In [12]:
arbspec(lambda t: cos(2*pi*100.0*t)**2, 2.0, 1.0/1000.0)
arbspec(lambda t: (cos(2*pi*100.0*t)+cos(2*pi*150.0*t))**2, 2.0, 1.0/1000.0)


def genbandpassf(ntaps, bottomf, topf, Ts):
    q = bottomf/(1/Ts)
    r = topf/(1/Ts)

    b = scipy.signal.remez(ntaps, [0,q*0.98,q,r,r*1.02,0.5], [0,1,0])
    return b

b = genbandpassf(100, 100, 300, 1.0/1000.0)
x = random.uniform(-1.0,1.0, 3.0*1000.0)
y = scipy.signal.lfilter(b,1,x)
plotspec(y**2, 1.0/1000.0)

3.15. (skipped)

3.17. Suppose y(t) = g(x(t)) is a posterizer: +1 if x(t) > 0, -1 if x(t) <= 0. Find the spectrum of its output when the input is:

  1. x(t) = cos(2pif*t) for f = 100Hz
  2. x(t) = cos(2pif1t) + cos(2pif2t) for f1=100 and f2=150Hz
In [18]:
def posterize(f):
    def s(t):
        return sign(f(t))
    return s

arbspec( posterize(lambda t: cos(2*pi*100*t)), 2.0, 1.0/1000.0)
arbspec( posterize(lambda t: cos(2*pi*100*t)+cos(2*pi*150*t)), 2.0, 1.0/1000.0)

3.18. Suppose the output of a nonlinear block with input x(t) is y(t) = x**2(t)

  1. cos(2pif*t+phi), f=100, phi=0.5
  2. cos(2pif1t)+cos(2pif2t), f1=100, f2=150Hz
  3. cos(2pif*t+phi) + n(t), f=100Hz, phi=0.5, n is white noise
In [21]:
def squaring(f):
    def s(t):
        return (f(t))**2
    return s

Ts=1.0/1000.0
arbspec( squaring(lambda t: cos(2*pi*100*t+0.5)), 2.0, Ts)
arbspec( squaring(lambda t: cos(2*pi*100*t)+cos(2*pi*150*t)), 2.0, Ts)

# Do it once without squaring, to see how the noise looks
arbspec( squaring(lambda t: cos(2*pi*100*t+0.5) + random.uniform(-1.0,1.0,len(t))), 2.0, Ts)

# Now add squaring
arbspec( lambda t: cos(2*pi*100*t+0.5) + random.uniform(-1.0,1.0,len(t)), 2.0, Ts)

3.19. Using the quantalph() function, given x(t) = a vector of length n, taken via randn (the standard normal distribution). Quantize to [-3,-1,1,3].

  1. What percentage of the values are 1 or 3?
  2. Plot the spectrum of the input and the output.
  3. Now let x=3*randn(1,n) and do the above.
In [26]:
def quantalph(x, alphabet):
    alphabet.sort()
    
    n = len(alphabet)
    
    untouched = x < (x + 1)
    
    y = copy(x)
    
    for i in range(n):
        candidates = logical_and(untouched, (x < alphabet[i]))
        y[candidates] = alphabet[i]
        untouched = logical_and(untouched, logical_not(candidates))
        
    y[untouched] = alphabet[-1]
    return y
In [28]:
x = random.normal(0,1, 100)
alphabet = [-3,3,-1,1]
y = quantalph(x, alphabet)
hist(y)

plotspec(x, 1.0/100.0)
plotspec(y, 1.0/100.0)
In [30]:
x = 3.0*random.normal(0,1, 100)
alphabet = [-3,3,-1,1]
y = quantalph(x, alphabet)
hist(y)

plotspec(x, 1.0/100.0)
plotspec(y, 1.0/100.0)

3.20. Modulate the following signals with a carrier wave of frequency 1kHz

  1. x(t) = 100Hz + 150Hz
  2. square wave of 150Hz
  3. noise signal with all energy below 300Hz
  4. noise between 2000 and 2300 Hz
  5. noise below 1500Hz
In [33]:
def modulate(fc, x):
    def s(t):
        return x(t) * cos(2*pi*fc*t)
    return s

arbspec(modulate(1000.0, lambda t: cos(2*pi*100*t)+cos(2*pi*150*t)), 2.0, 1.0/10000.0)
In [35]:
arbspec(modulate(1000.0, lambda t: sign(cos(2*pi*150*t))), 2.0, 1.0/10000.0)
In [37]:
def q(t):
    b = genbandpassf(100, 0.001, 300, 1.0/1000.0)
    x = random.uniform(-1.0,1.0, len(t))
    y = scipy.signal.lfilter(b,1,x)
    return y


arbspec(modulate(1000.0, q), 2.0, 1.0/10000.0)
In [40]:
def q(t):
    b = genbandpassf(100, 2000, 2300, 1.0/10000.0)
    x = random.uniform(-1.0,1.0, len(t))
    y = scipy.signal.lfilter(b,1,x)
    return y


arbspec(modulate(1000.0, q), 2.0, 1.0/10000.0)
In [41]:
def q(t):
    b = genbandpassf(100, 0.001, 1500, 1.0/10000.0)
    x = random.uniform(-1.0,1.0, len(t))
    y = scipy.signal.lfilter(b,1,x)
    return y


arbspec(modulate(1000.0, q), 2.0, 1.0/10000.0)